﻿using System;
using System.Diagnostics;
using EnvDTE;
using GalaSoft.MvvmLight.Threading;
using Greycastle.RUBuildin.View;

namespace Greycastle.RUBuildin
{
    internal class ApplicationWatcher
    {
        private readonly SolutionEvents _eventRegistrations;
        private readonly DTE _app;
        private bool _disposed;
        private BubbleWindow _window;
        private Events _solutionEvents;

        public ApplicationWatcher(DTE applicationObject)
        {
            Debug.WriteLine("Entering ApplicationWatcher(DTE2 {1}) of: {0}", this, applicationObject.FullName);
            
            AssemblyResolver.EnableResolutionFromManifestFolder();
            DispatcherHelper.Initialize();

            _app = applicationObject;
            _eventRegistrations = applicationObject.Events.SolutionEvents;
            _eventRegistrations.Opened += OnSolutionOpened;
            _eventRegistrations.BeforeClosing += OnSolutionClosing;
            
            if(_app.Solution != null)
                OnSolutionOpened();
        }

        public void Dispose()
        {
            if (_disposed)
                return;

            Debug.WriteLine("Disposing ApplicationWatcher: {0}", this);
            _disposed = true;
            _eventRegistrations.Opened -= OnSolutionOpened;
            _eventRegistrations.BeforeClosing -= OnSolutionClosing;
        }

        private void OnSolutionClosing()
        {
            Debug.WriteLine("ApplicationWatcher.OnSolutionClosing: {0}", (object)_app.Solution.FullName);
            _solutionEvents.BuildEvents.OnBuildBegin -= BuildBegun;
            _solutionEvents.BuildEvents.OnBuildDone -= BuildFinished;
        }

        private void OnSolutionOpened()
        {
            Debug.WriteLine("ApplicationWatcher.OnSolutionOpened: {0}", (object)_app.Solution.FullName);
            _solutionEvents = _app.Solution.DTE.Events;
            _solutionEvents.BuildEvents.OnBuildBegin += BuildBegun;
            _solutionEvents.BuildEvents.OnBuildDone += BuildFinished;
        }

        private void BuildFinished(vsBuildScope scope, vsBuildAction action)
        {
            Debug.WriteLine("ApplicationWatcher.BuildFinished (vsBuildScope {0}, vsBuildAction {1})", scope, action);

            _window.Close();
            _window = null;
        }

        private void BuildBegun(vsBuildScope scope, vsBuildAction action)
        {
            Debug.WriteLine("ApplicationWatcher.BuildBegun (vsBuildScope {0}, vsBuildAction {1})", scope, action);
            
            _window = new BubbleWindow { DataContext = new BubbleWindowViewModel(new IntPtr(_app.Solution.DTE.MainWindow.HWnd)) };
            _window.Show();
        }
    }
}